package legumes.client.ui.otherboxes;

import legumes.client.evt.customer.CustomerOrderChangedEvent;
import legumes.client.evt.customer.CustomerOrderChangedEventHandler;
import legumes.client.evt.main.UserConnectedEvent;
import legumes.client.evt.main.UserConnectedEventHandler;
import legumes.client.evt.manager.EventBusManager;
import legumes.client.evt.store.PlaceDeliverySelectionChangedEvent;
import legumes.client.evt.store.PlaceDeliverySelectionChangedEventHandler;
import legumes.client.evt.store.StoreStateChangedEvent;
import legumes.client.evt.store.StoreStateChangedEventHandler;
import legumes.client.resources.PNResources;
import legumes.client.services.callbacks.HasOrderConflictCallback;
import legumes.client.services.callbacks.SaveOrderCallback;
import legumes.client.services.util.rpc.RPCCallSequencer;
import legumes.client.ui.Authentication;
import legumes.client.ui.otherboxes.order.OrderViewWindow;
import legumes.client.ui.widgets.utils.Formatters;
import legumes.client.ui.widgets.window.connexion.ConnexionWindow;
import legumes.shared.domain.LoginException;
import legumes.shared.domain.Order;
import legumes.shared.domain.SellSessionForCustomer;

import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;

public class OrderBoxPanel extends Window {
	
	private Canvas totalCanvas;
	private SellSessionForCustomer sellSessionForCustomer;
	private float totalPrice = 0f;
	
	private HLayout vlMainLayout;
	
	private VLayout vlStoreOpened;
	private VLayout vlStoreClosed;
	
	public OrderBoxPanel() {
		super();
		setWidth100();
		setHeight(80);
		setMargin(5);
		setMembersMargin(5);
		
		setTitle("<img src=\"" + PNResources.INSTANCE.shoppingChartIcon().getURL() + "\" />&nbsp;Mon panier");
		
		setShowCloseButton(false);
        setShowMinimizeButton(true);
		setCanDrag(false);
		setCanDragReposition(false);
		
		buildStoreOpenPanel();
		buildStoreClosePanel();
		
		vlMainLayout = new HLayout();
		vlMainLayout.setWidth100();
		vlMainLayout.setHeight100();
		vlMainLayout.setMembers(vlStoreOpened);
		
//		VLayout vlMainLayoutWithPaiementMode = new VLayout();
//		vlMainLayoutWithPaiementMode.setWidth100();
//		vlMainLayoutWithPaiementMode.setHeight100();
//		Img imgPaiementModeImg = new Img(
//				PNResources.INSTANCE.titresRestaurantImg().getURL(),
//				148, 30);
//		imgPaiementModeImg.setMargin(3);
//		imgPaiementModeImg.setLayoutAlign(Alignment.CENTER);
//		vlMainLayoutWithPaiementMode.setMembers(vlMainLayout, imgPaiementModeImg);
		
		bind();
		setVisible(false);
		
		addItem(vlMainLayout);
	}
	
	private void bind(){

		EventBusManager.getInstance().getEventBus().addHandler(
				CustomerOrderChangedEvent.TYPE, 
				new CustomerOrderChangedEventHandler(){

					@Override
					public void onOrderChanged(CustomerOrderChangedEvent event) {
						if( event.isPriceAdded() ){
							totalPrice += event.getPrice();
						} else {
							totalPrice -= event.getPrice();
							if( totalPrice < 0 ){
								totalPrice = 0f;
							}
						}
						updateTotalPrice();
					}
					
				});
		
		EventBusManager.getInstance().getEventBus().addHandler(
				PlaceDeliverySelectionChangedEvent.TYPE, 
				new PlaceDeliverySelectionChangedEventHandler(){

					@Override
					public void onStoreSelectionChanged(
							PlaceDeliverySelectionChangedEvent event) {
						if (event.getStore() != null){
							OrderBoxPanel.this.show();
						} else {
							OrderBoxPanel.this.hide();
						}
					}
					
				});
		
		EventBusManager.getInstance().getEventBus().addHandler(
				StoreStateChangedEvent.TYPE,
				new StoreStateChangedEventHandler() {
					
					@Override
					public void onStoreStateChanged(StoreStateChangedEvent event) {
						if( event.isStoreOpen() ){
							vlMainLayout.setMembers(vlStoreOpened);
						} else {
							vlMainLayout.setMembers(vlStoreClosed);
						}
					}
				}
		);
		
		EventBusManager.getInstance().getEventBus().addHandler(
				UserConnectedEvent.TYPE, 
				new UserConnectedEventHandler(){

					@Override
					public void onUserConnected(UserConnectedEvent event) {
						if(! isVisible() ){
							setVisible(true);
						}
					}
				});
	}
	
	private void buildStoreClosePanel(){
		Canvas storeClosedCanvas = new Canvas();  
		storeClosedCanvas.setPrefix("<b>Magasin ferm&eacute; : </b>");   
		storeClosedCanvas.setPadding(5);  
		storeClosedCanvas.setHeight(21);  
		storeClosedCanvas.setWidth100();
		storeClosedCanvas.setContents(storeClosedCanvas.getPrefix() + " Ouverture Lundi prochain...");
		
		
		vlStoreClosed = new VLayout();
		vlStoreClosed.setWidth100();
		vlStoreClosed.setHeight100();
		vlStoreClosed.setMembers(storeClosedCanvas);
	}
	
	private void buildStoreOpenPanel(){
		totalCanvas = new Canvas();  
		totalCanvas.setWidth(90);
		totalCanvas.setPrefix("<b>Total : </b>");
		totalCanvas.setContents(totalCanvas.getPrefix() + Formatters.formatPrice(0, true));
        
		Button validateButton = new Button();
		validateButton.setLayoutAlign(Alignment.CENTER);
		validateButton.setAutoFit(true);
		validateButton.setTitle("Valider ma commande");
		validateButton.setIcon( PNResources.INSTANCE.validateIcon().getURL() );
		validateButton.addClickHandler(new ClickHandler() {  
            public void onClick(ClickEvent event) {
            	if( totalPrice > 0 ){
            		saveOrder();
            	} else {
            		SC.say("Votre commande est vide.");
            	}
            }  
        });  
        
		Button showOrderButton = new Button();
		showOrderButton.setAutoFit(true);
		showOrderButton.setAlign(Alignment.RIGHT);
		showOrderButton.setTitle("D&eacute;tails");
		showOrderButton.setIcon( PNResources.INSTANCE.viewDetailsIcon().getURL() );
		
		showOrderButton.addClickHandler(new ClickHandler() {  
            public void onClick(ClickEvent event) {
            	showOrderViewWindow();
            }  
        }); 
		
		vlStoreOpened = new VLayout();
		HLayout hl = new HLayout();
		hl.setWidth100();
		hl.setAutoHeight();
		hl.setLayoutAlign(Alignment.CENTER);
		hl.setMargin(5);
		hl.setMembersMargin(5);
		hl.setMembers(totalCanvas, showOrderButton, validateButton);
		vlStoreOpened.setMembers(hl);
		
	}
	
	private void showOrderViewWindow(){
		//TODO SMA Manage current OderPart
		new OrderViewWindow(sellSessionForCustomer, sellSessionForCustomer.getOrder().getOrderParts().get(0));
	}
	
	private void updateTotalPrice(){
		String price = Formatters.formatPrice(totalPrice, true);
		totalCanvas.setContents(totalCanvas.getPrefix() + price);
	}
	
	public void initData(SellSessionForCustomer ssfc_){
		sellSessionForCustomer = ssfc_;
	}
	
	public Order getOrder() {
		return sellSessionForCustomer == null ? 
				null : sellSessionForCustomer.getOrder();
	}
	
	/**
	 * 
	 */
	private void saveOrder() {
		final RPCCallSequencer callSequencer = new RPCCallSequencer();

		final HasOrderConflictCallback hasOrderConflictCallback = new HasOrderConflictCallback(
				sellSessionForCustomer.getCreationDate(),
				sellSessionForCustomer.getOrder());
		if (Authentication.isAuthenticated()) {
			// 1
			callSequencer.addCall(hasOrderConflictCallback);
		}

		final RPCCallSequencer callSequencer2 = new RPCCallSequencer(
				"Enregistrement en cours...");
		final SaveOrderCallback saveOrderCallback = new SaveOrderCallback(
				sellSessionForCustomer.getCreationDate(), 
				getOrder(), true);
		callSequencer2.addCall(saveOrderCallback);

		// 2
		callSequencer.addRunnable(new Runnable() {
			public void run() {
				if (Authentication.isAuthenticated()
						&& hasOrderConflictCallback.hasOrderConflict()) {
					SC.confirm("Confirmation", 
							"Vous avez d&eactue;j&agrave; command&eactue;.<br> "
							+ "Souhaitez-vous conserver les commandes existantes ?<br>"
							+ "Une fois cette fen&ecirc;tre ferm&eactue;e, toutes vos commandes en cours seront affich&eacute;es.<br>"
							+ "Vous pourrez les modifier.", 
							new BooleanCallback(){

								@Override
								public void execute(Boolean value) {
									if (value.booleanValue()) {
										saveOrderCallback.setMerge(true);
										callSequencer2.callSequence();
									} else {
										saveOrderCallback.setMerge(false);
										callSequencer2.callSequence();
									}
								}
					});
				} // end if
				else {
					callSequencer2.callSequence();
				}
			}
		});

		callSequencer2.addRunnable(new Runnable() {
			public void run() {
				if (saveOrderCallback.hasFailed()
						&& saveOrderCallback.getThrowable() instanceof LoginException) {
					new ConnexionWindow();
				} else {
					saveOrderCallback.getSavedOrder();
				}
			}
		});

		callSequencer.callSequence();
	}
	
}
